<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>2_key的作用</title>
    <!-- 引入react核心库 -->
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <!-- 引入babel,用于将jsx转换为js -->
    <script type="text/javascript" src="../React-js/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/babel">
      /*
         经典面试题：
            1).react/vue中的key有什么作用? (key的内部原理是什么?)
            2).为什么遍历列表时,key最好不要用index?

          1.虚拟DOM中key的作用：
             1). 简单的说: key是虚拟DOM对象的标识，在更新显示时key起着极其重要的作用。

             2). 详细的说：当状态中的数据发生变化时，react会根据【新数据】生成【新的虚拟DOM】
                          随后React进行【新虚拟DOM】与【就虚拟DOM】的diff比较，比较规则如下：

                    a. 旧虚拟DOM找到了与新虚拟DOM相同的key：
                          (1).若虚拟DOM中内容没变，直接使用之前的真实DOM
                          (2).若虚拟DOM中内容变了，则生成新的真实DOM，替换掉页面中之前的真实DOM

                    b. 旧虚拟DOM中未找到与新虚拟DOM相同的key
                         根据数据创建新的真实DOM,随后渲染到页面

          2.用index作为key可能会引发的问题:
                  1. 若对数据进行：逆序添加、逆序删除等破坏顺序操作：
                         会产生没有必要的真实DOM更新 ==> 界面效果没问题，当效率低

                  2. 如果结构中还包含输入类的DOM：
                          会产生错误DOM更新 ==>  界面有问题

                  3. 注意! 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作，
                      仅用于渲染列表用于展示，使用index作为key是没有问题的。
          
         3.开发中如何选择key?
            1.最好使用每条数据的唯一标识作为key 例如 id 手机号 身份证号
            2.如果确认只是简单的展示数据，用index 也可以

       */
      class Person extends React.Component {
        state = {
          persons: [
            { id: 1, name: '哈哈', age: 22 },
            { id: 2, name: 'hh', age: 21 },
            { id: 3, name: 'cxh', age: 20 },
          ],
        };

        add = () => {
          const { persons } = this.state;
          const p = {
            id: persons.length + 1,
            name: 'ccc',
            age: 24,
          };
          this.setState({
            persons: [p, ...persons],
          });
        };

        render() {
          return (
            <div>
              <h2>展示人员信息</h2>
              <button onClick={this.add}>添加cc</button>
              <h3>用index (索引值)</h3>
              <ul>
                {this.state.persons.map((item, index) => {
                  return (
                    <li key={index}>
                      {item.name}------{item.age}
                      <input type="text" />
                    </li>
                  );
                })}
              </ul>
              <br />
              <br />
              <h3>用id (唯一标识符)</h3>
              <ul>
                {this.state.persons.map((item) => {
                  return (
                    <li key={item.id}>
                      {item.name}------{item.age}
                      <input type="text" />
                    </li>
                  );
                })}
              </ul>
            </div>
          );
        }
      }

      const root = ReactDOM.createRoot(document.getElementById('root'));
      root.render(<Person />);
    </script>
  </body>
</html>
